<template>
  <el-container class="fm2-container app-container home">
    <el-main class="fm2-main">
      <el-container>
        <el-container class="center-container" direction="vertical">
          <el-header class="btn-bar" style="height: 45px">
            <slot name="action"> </slot>
            <!-- <el-button type="text" size="medium" icon="el-icon-upload2" :disabled="true">导入</el-button> -->
            <!-- <el-button type="text" size="medium" icon="el-icon-download" @click="handleExportXmlAction">导出XML</el-button> -->
            <!-- <el-button type="text" size="medium" icon="el-icon-download" @click="handleExportSvgAction">导出SVG</el-button> -->
            <!-- <el-button type="text" size="medium" icon="el-icon-tickets" @click="xmlVisible = !xmlVisible">预览</el-button> -->
            <!-- <el-button type="text" size="medium" icon="el-icon-delete" @click="handleClear">清除</el-button> -->
            <el-button
              type="text"
              size="medium"
              icon="el-icon-document"
              @click="open = true"
              >保存</el-button
            >
          </el-header>
          <el-main>
            <div class="containers" :style="{ height: getContainerHeight }">
              <div class="canvas" ref="canvas" />

              <!-- <el-dialog
                :visible.sync="xmlVisible"
                title="XML"
                :fullscreen="false"
                top="10vh"
              >
                <vue-ace-editor
                  v-model="process.xml"
                  @init="editorInit"
                  lang="xml"
                  theme="chrome"
                  width="100%"
                  height="400"
                  :options="{ wrap: true, readOnly: true }"
                >
                </vue-ace-editor>
                <span slot="footer" class="dialog-footer">
                  <el-button
                    icon="el-icon-document"
                    v-clipboard:copy="process.xml"
                    v-clipboard:success="onCopy"
                    >复 制</el-button
                  >
                  <el-button
                    icon="el-icon-close"
                    type="primary"
                    @click="xmlVisible = false"
                    >关闭</el-button
                  >
                </span>
              </el-dialog> -->
            </div>
          </el-main>
        </el-container>

        <el-aside class="widget-config-container">
          <el-container>
            <!-- <el-header height="45px">
              <div
                class="config-tab"
                :class="{ active: configTab == 'node' }"
                @click="handleConfigSelect('node')"
              >
                节点属性
              </div>
              <div
                class="config-tab"
                :class="{ active: configTab == 'process' }"
                @click="handleConfigSelect('process')"
              >
                流程属性
              </div>
            </el-header> -->
            <el-main class="config-content">
              <node-property-panel
                v-if="bpmnModeler && configTab == 'node'"
                :modeler="bpmnModeler"
              />
              <process-property-panel
                v-if="configTab == 'process'"
                :process-data="process"
              ></process-property-panel>
            </el-main>
          </el-container>
        </el-aside>
      </el-container>
    </el-main>
    <el-dialog title="流程信息" :visible.sync="open" width="30%" center>
      <el-form
        :model="dialogForm"
        ref="numberValidateForm"
        label-width="100px"
        class="demo-ruleForm"
      >
        <el-form-item
          label="流程名称"
          prop="name"
          :rules="[{ required: true, message: '流程名称不能为空！' }]"
        >
          <el-input v-model="dialogForm.name"></el-input>
        </el-form-item>
        <el-form-item label="流程描述" prop="description">
          <el-input v-model="dialogForm.description"></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="open = false" class="dialogCancel">取 消</el-button>
        <el-button type="primary" @click="handleSave" class="tableAdd"
          >确 定</el-button
        >
      </span>
    </el-dialog>
  </el-container>
</template>

<script>
// bpmn-js 设计器
import BpmnModeler from "bpmn-js/lib/Modeler";
// 对flowable的扩展
import flowableExtensionModule from "jp-flowable-bpmn-moddle/lib";
import flowableModdle from "jp-flowable-bpmn-moddle/resources/flowable";

import NodePropertyPanel from "./NodePropertyPanel"; // 属性面板
import ProcessPropertyPanel from "./ProcessPropertyPanel";

import BpmData from "./BpmData";
import VueAceEditor from "vue2-ace-editor";
import { addProcess } from "@/api/approvalManage/processManage.js";
export default {
  props: {
    processName: {
      type: String,
      default: "流程1567044459787",
    },
    processKey: {
      type: String,
      default: "process1567044459787",
    },
    processDescription: {
      type: String,
      default: "描述",
    },
  },

  components: {
    NodePropertyPanel,
    ProcessPropertyPanel,
    VueAceEditor,
  },

  data() {
    return {
      bpmnModeler: null,
      process: {
        name: this.processName,
        id: this.processKey,
        description: this.processDescription,
        xml: "",
        svg: "",
      },
      configTab: "node",
      nodeProcessSelect: null,
      open: false,
      xmlVisible: false,
      element: null,
      bpmData: new BpmData(),
      dialogForm: {
        name: "",
        description: "",
      },
    };
  },

  methods: {
    /**
     * bind SVG element height.
     */
    getContainerHeight() {
      return document.body.offsetHeight - 75 + "px";
    },
    /**
     * init ace editor.
     */
    editorInit: function () {
      require("brace/ext/language_tools"); //language extension prerequsite...
      require("brace/mode/xml"); //language
      require("brace/theme/chrome");
    },
    /**
     * init
     */
    createNewDiagram() {
      // 初始化XML文本
      this.process.xml = `<?xml version="1.0" encoding="UTF-8"?>
<bpmn2:definitions xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
                   xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
                   targetNamespace="http://bpmn.io/schema/bpmn"
                   xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd">
  <bpmn2:process id="${this.processKey}" name="${this.processName}">
    <bpmn2:documentation>${this.processDescription}</bpmn2:documentation>
    <bpmn2:startEvent id="StartEvent_01ydzqe" />
  </bpmn2:process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="process1567044459787">
      <bpmndi:BPMNShape id="StartEvent_01ydzqe_di" bpmnElement="StartEvent_01ydzqe">
        <dc:Bounds x="242" y="212" width="36" height="36" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="247" y="263" width="25" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</bpmn2:definitions>`;
      // 将字符串转换成图显示出来
      this.bpmnModeler.importXML(this.process.xml, (err) => {
        if (err) {
          console.error(err);
        } else {
          this.adjustPalette();
        }
      });
    },

    // 调整左侧工具栏排版
    adjustPalette() {
      try {
        // 获取 bpmn 设计器实例
        const canvas = this.$refs.canvas;
        const djsPalette = canvas.children[0].children[1].children[4];
        const djsPalStyle = {
          width: "130px",
          padding: "5px",
          background: "white",
          left: "20px",
          borderRadius: 0,
        };
        for (var key in djsPalStyle) {
          djsPalette.style[key] = djsPalStyle[key];
        }
        const palette = djsPalette.children[0];
        const allGroups = palette.children;
        allGroups[0].style["display"] = "none";
        // 修改控件样式
        for (var gKey in allGroups) {
          const group = allGroups[gKey];
          for (var cKey in group.children) {
            const control = group.children[cKey];
            const controlStyle = {
              display: "flex",
              justifyContent: "flex-start",
              alignItems: "center",
              width: "100%",
              padding: "5px",
            };
            if (
              control.className &&
              control.dataset &&
              control.className.indexOf("entry") !== -1
            ) {
              const controlProps = this.bpmData.getControl(
                control.dataset.action
              );
              control.innerHTML = `<div style='font-size: 14px;font-weight:500;margin-left:15px;'>${controlProps["title"]}</div>`;
              if (controlProps["tooltip"]) {
                control.title = controlProps["tooltip"];
              }
              for (var csKey in controlStyle) {
                control.style[csKey] = controlStyle[csKey];
              }
            }
          }
        }
      } catch (e) {
        console.log(e);
      }
    },

    // 当图发生改变的时候会调用这个函数，这个data就是图的xml
    setEncoded(type, data) {
      // 把xml转换为URI，下载要用到的
      const encodedData = encodeURIComponent(data);
      if (data) {
        if (type === "XML") {
          // 获取到图的xml，保存就是把这个xml提交给后台
          this.process.xml = data;
          return {
            filename: this.process.name + ".xml",
            href: "data:application/bpmn20-xml;charset=UTF-8," + encodedData,
            data: data,
          };
        }
        if (type === "SVG") {
          this.process.svg = data;
          return {
            filename: this.process.name + ".svg",
            href: "data:application/text/xml;charset=UTF-8," + encodedData,
            data: data,
          };
        }
      }
    },
    /**
     * 导出BPMN XML文件
     */
    // handleExportXmlAction() {
    //   const _this = this;
    //   this.bpmnModeler.saveXML({ format: true }, function(err, xml) {
    //     if (err) {
    //       console.error(err);
    //     }
    //     let {filename, href} = _this.setEncoded('XML', xml);
    //     if (href && filename) {
    //       let a = document.createElement('a');
    //       a.download = filename; //指定下载的文件名
    //       a.href = href; //  URL对象
    //       a.click(); // 模拟点击
    //       URL.revokeObjectURL(a.href); // 释放URL 对象
    //     }
    //   });
    // },
    /**
     * 导出BPMN SVG文件
     */
    // handleExportSvgAction() {
    //   const _this = this;
    //   this.bpmnModeler.saveSVG(function (err, svg) {
    //     if (err) {
    //       console.error(err);
    //     }
    //     let {filename, href} = _this.setEncoded('SVG', svg);
    //     if (href && filename) {
    //       let a = document.createElement('a');
    //       a.download = filename;
    //       a.href = href;
    //       a.click();
    //       URL.revokeObjectURL(a.href);
    //     }
    //   });
    // },
    /**
     * 清空设计器内容
     */
    // handleClear() {
    //   this.createNewDiagram();
    // },
    /**
     * 复制内容到剪切板成功回调
     */
    // onCopy() {
    //   this.$message.success("内容复制成功");
    // },
    /**
     * 配置Tab切换
     */
    // handleConfigSelect(value) {
    //   this.configTab = value;
    // },
    // 保存
    handleSave() {
      // this.$route.query.data addProcess
      const params = {
        id: this.$route.query.data,
        jsonXml: JSON.stringify(this.process.xml),
        svgXml: this.process.svg,
        name: this.dialogForm.name,
        description: this.dialogForm.description,
      };
      console.log(typeof params.json_xml);
      this.$refs.numberValidateForm.validate((valid) => {
        if (valid) {
          console.log(this.process);
          addProcess(params).then((res) => {
            this.$message.success("操作成功！");
            this.$router.push({
              path: "/approvalManage/processManage",
            });
          });
        } else {
          console.log("error submit!!");
          return false;
        }
      });
    },
  },

  mounted() {
    const canvas = this.$refs.canvas;
    // 生成实例
    this.bpmnModeler = new BpmnModeler({
      container: canvas,
      additionalModules: [flowableExtensionModule],
      moddleExtensions: {
        flowable: flowableModdle,
      },
    });

    // 监听流程图改变事件
    const _this = this;
    this.bpmnModeler.on("commandStack.changed", () => {
      _this.bpmnModeler.saveSVG({ format: true }, function (err, svg) {
        _this.setEncoded("SVG", err ? null : svg);
      });
      _this.bpmnModeler.saveXML({ format: true }, function (err, xml) {
        _this.setEncoded("XML", err ? null : xml);
      });
    });

    // 新增流程定义
    this.createNewDiagram();
  },
  watch: {
    "process.xml": {
      handler(val) {
        this.$nextTick(() => {
          // console.log(val)
        });
      },
    },
  },
};
</script>

<style scoped lang="scss">
/*左边工具栏以及编辑节点的样式*/
@import "~bpmn-js/dist/assets/diagram-js.css";
@import "~bpmn-js/dist/assets/bpmn-font/css/bpmn.css";
@import "~bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css";
@import "~bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css";
.containers {
  /*position: absolute;*/
  background-color: #ffffff;
  width: 100%;
  height: 600px;

  .canvas {
    width: 100%;
    height: 100%;
  }
  .panel {
    position: absolute;
    right: 0;
    top: 50px;
    width: 300px;
  }
  ::v-deep .bjs-powered-by {
    display: none;
  }
  .toolbar {
    position: absolute;
    top: 0;
    right: 320px;
    height: 40px;
    width: 600px;
    border: 1px solid red;
    a {
      text-decoration: none;
      margin: 5px;
      color: #409eff;
    }
  }
  ::v-deep .bpmn-icon-intermediate-event-none,
  ::v-deep .bpmn-icon-gateway-none,
  ::v-deep .bpmn-icon-task,
  ::v-deep .bpmn-icon-subprocess-expanded,
  ::v-deep .bpmn-icon-data-object,
  ::v-deep .bpmn-icon-data-store,
  ::v-deep .bpmn-icon-participant,
  ::v-deep .bpmn-icon-group {
    display: none !important;
  }
}
</style>
